/*
 * Copyright (c) 2008 Benoit Bouchez, Nicolas Giard
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.noocodecommit.wicket.stuff.jquery.plugin.effects;

import org.apache.wicket.Component;

/**
 * JQuery effects base class
 * 
 * @author Benoit Bouchez
 * 
 */
public class JQAnimation
{
	/** Blind animation tag */
	public static String ANIMATIONSTYLE_BLIND = "blind";
	/** Bounce animation tag */
	public static String ANIMATIONSTYLE_BOUNCE = "bounce";
	/** Clip animation tag */
	public static String ANIMATIONSTYLE_CLIP = "clip";
	/** Drop animation tag */
	public static String ANIMATIONSTYLE_DROP = "drop";
	/** Explode animation tag */
	public static String ANIMATIONSTYLE_EXPLODE = "explode";
	/** Fold animation tag */
	public static String ANIMATIONSTYLE_FOLD = "fold";
	/** Highlight animation tag */
	public static String ANIMATIONSTYLE_HIGHLIGHT = "highlight";
	/** Pulsate animation tag */
	public static String ANIMATIONSTYLE_PULSATE = "pulsate";
	/** Size animation tag */
	public static String ANIMATIONSTYLE_SIZE = "size";
	/** Scale animation tag */
	public static String ANIMATIONSTYLE_SCALE = "scale";
	/** Puff animation tag */
	public static String ANIMATIONSTYLE_PUFF = "puff";
	/** Shake animation tag */
	public static String ANIMATIONSTYLE_SHAKE = "shake";
	/** Slide animation tag */
	public static String ANIMATIONSTYLE_SLIDE = "slide";
	/** Transfer animation tag */
	public static String ANIMATIONSTYLE_TRANSFER = "transfer";

	/** Speed animation value (slow) */
	public static int ANIMATIONSPEED_SLOW = 600;
	/** Speed animation value (default) */
	public static int ANIMATIONSPEED_DEFAULT = 400;
	/** Speed animation value (fast) */
	public static int ANIMATIONSPEED_FAST = 200;

	/** Animation mode effect */
	public static String ANIMATIONMODE_EFFECT = "effect";
	/** Animation mode show */
	public static String ANIMATIONMODE_SHOW = "show";
	/** Animation mode hide */
	public static String ANIMATIONMODE_HIDE = "hide";
	/** Animation mode toggle */
	public static String ANIMATIONMODE_TOGGLE = "toggle";

	/**
	 * Generates an effect script string on a Wicket component with the given animation.
	 * 
	 * @param component
	 *            target of the effect
	 * @param animation
	 *            animation to apply
	 * @return a javascript string
	 */
	public static String effect(Component component, IJQAnimation animation)
	{
		return effect(component, animation, ANIMATIONSPEED_DEFAULT);
	}

	/**
	 * Generates an effect script string on a Wicket component with the given animation.
	 * 
	 * @param component
	 *            target of the effect
	 * @param animation
	 *            animation to apply
	 * @param speed
	 *            animation speed
	 * @return a javascript string
	 */
	public static String effect(Component component, IJQAnimation animation, int speed)
	{
		return effect(component, animation, speed, "");
	}

	/**
	 * Generates an effect script string on a Wicket component with the given animation.
	 * 
	 * @param component
	 *            target of the effect
	 * @param animation
	 *            animation to apply
	 * @param speed
	 *            animation speed
	 * @param callbackScript
	 *            animation callback script
	 * @return a javascript string
	 */
	public static String effect(Component component, IJQAnimation animation, int speed, String callbackScript)
	{
		if (!animation.isSupportedAnimationMode(JQAnimation.ANIMATIONMODE_EFFECT))
		{
			throw new JQAnimationModeNotSupportedException(JQAnimation.ANIMATIONMODE_EFFECT, animation.getAnimateStyle());
		}
		return "$('#" + component.getMarkupId() + "').effect('" + animation.getAnimateStyle() + "'" + (animation.getAnimateOptions().length() > 0 ? ", " + animation.getAnimateOptions() : "") + ", " + speed + ", function(){" + callbackScript + "});";
	}

	/**
	 * Generates an effect script string on a JQuery selector with the given animation.
	 * 
	 * @param selector
	 *            JQuery selector
	 * @param animation
	 *            animation to apply
	 * @return a javascript string
	 */
	public static String effect(String selector, IJQAnimation animation)
	{
		return effect(selector, animation, ANIMATIONSPEED_DEFAULT);
	}

	/**
	 * Generates an effect script string on a JQuery selector with the given animation.
	 * 
	 * @param selector
	 *            JQuery selector
	 * @param animation
	 *            animation to apply
	 * @param speed
	 *            animation speed
	 * @return a javascript string
	 */
	public static String effect(String selector, IJQAnimation animation, int speed)
	{
		return effect(selector, animation, speed, "");
	}

	/**
	 * Generates an effect script string on a JQuery selector with the given animation.
	 * 
	 * @param selector
	 *            JQuery selector
	 * @param animation
	 *            animation to apply
	 * @param speed
	 *            animation speed
	 * @param callbackScript
	 *            animation callback script
	 * @return a javascript string
	 */
	public static String effect(String selector, IJQAnimation animation, int speed, String callbackScript)
	{
		if (!animation.isSupportedAnimationMode(JQAnimation.ANIMATIONMODE_EFFECT))
		{
			throw new JQAnimationModeNotSupportedException(JQAnimation.ANIMATIONMODE_EFFECT, animation.getAnimateStyle());
		}
		return "$(" + selector + ").effect('" + animation.getAnimateStyle() + "'" + (animation.getAnimateOptions().length() > 0 ? ", " + animation.getAnimateOptions() : "") + ", " + speed + ", function(){" + callbackScript + "});";
	}

	/**
	 * Generates a script to show a Wicket component.
	 * 
	 * @param component
	 *            component to show
	 * @return a javascript string
	 */
	public static String show(Component component)
	{
		return show(component, ANIMATIONSPEED_DEFAULT, "");
	}

	/**
	 * Generates a script to show a Wicket component.
	 * 
	 * @param component
	 *            component to show
	 * @param speed
	 *            animation speed
	 * @return a javascript string
	 */
	public static String show(Component component, int speed)
	{
		return show(component, speed, "");
	}

	/**
	 * Generates a script to show a Wicket component.
	 * 
	 * @param component
	 *            component to show
	 * @param speed
	 *            animation speed
	 * @param callbackScript
	 *            animation callback script
	 * @return a javascript string
	 */
	public static String show(Component component, int speed, String callbackScript)
	{
		return "$('#" + component.getMarkupId() + "').show(" + speed + ", function(){" + callbackScript + "});";
	}

	/**
	 * Generates a script to show a Wicket component with the given animation.
	 * 
	 * @param component
	 *            component to show
	 * @param animation
	 *            animation to apply
	 * @return a javascript string
	 */
	public static String show(Component component, IJQAnimation animation)
	{
		return show(component, animation, ANIMATIONSPEED_DEFAULT, "");
	}

	/**
	 * Generates a script to show a Wicket component with the given animation.
	 * 
	 * @param component
	 *            component to show
	 * @param animation
	 *            animation to apply
	 * @param speed
	 *            animation speed
	 * @return a javascript string
	 */
	public static String show(Component component, IJQAnimation animation, int speed)
	{
		return show(component, animation, speed, "");
	}

	/**
	 * Generates a script to show a Wicket component with the given animation.
	 * 
	 * @param component
	 *            component to show
	 * @param animation
	 *            animation to apply
	 * @param speed
	 *            animation speed
	 * @param callbackScript
	 *            animation callback script
	 * @return a javascript string
	 */
	public static String show(Component component, IJQAnimation animation, int speed, String callbackScript)
	{
		if (!animation.isSupportedAnimationMode(JQAnimation.ANIMATIONMODE_SHOW))
		{
			throw new JQAnimationModeNotSupportedException(JQAnimation.ANIMATIONMODE_SHOW, animation.getAnimateStyle());
		}
		return "$('#" + component.getMarkupId() + "').show('" + animation.getAnimateStyle() + "'" + (animation.getAnimateOptions().length() > 0 ? ", " + animation.getAnimateOptions() : "") + ", " + speed + ", function(){" + callbackScript + "});";
	}

	/**
	 * Generates a script to show a JQuery selector.
	 * 
	 * @param selector
	 *            JQuery selector
	 * @return a javascript string
	 */
	public static String show(String selector)
	{
		return show(selector, ANIMATIONSPEED_DEFAULT, "");
	}

	/**
	 * Generates a script to show a JQuery selector.
	 * 
	 * @param selector
	 *            JQuery selector
	 * @param speed
	 *            animation speed
	 * @return a javascript string
	 */
	public static String show(String selector, int speed)
	{
		return show(selector, speed, "");
	}

	/**
	 * Generates a script to show a JQuery selector.
	 * 
	 * @param selector
	 *            JQuery selector
	 * @param speed
	 *            animation speed
	 * @param callbackScript
	 *            animation callback script
	 * @return a javascript string
	 */
	public static String show(String selector, int speed, String callbackScript)
	{
		return "$(" + selector + ").show(" + speed + ", function(){" + callbackScript + "});";
	}

	/**
	 * Generates a script to show a JQuery selector with the given animation.
	 * 
	 * @param selector
	 *            JQuery selector
	 * @param animation
	 *            animation to apply
	 * @return a javascript string
	 */
	public static String show(String selector, IJQAnimation animation)
	{
		return show(selector, animation, ANIMATIONSPEED_DEFAULT, "");
	}

	/**
	 * Generates a script to show a JQuery selector with the given animation.
	 * 
	 * @param selector
	 *            JQuery selector
	 * @param animation
	 *            animation to apply
	 * @param speed
	 *            animation speed
	 * @return a javascript string
	 */
	public static String show(String selector, IJQAnimation animation, int speed)
	{
		return show(selector, animation, speed, "");
	}

	/**
	 * Generates a script to show a JQuery selector with the given animation.
	 * 
	 * @param selector
	 *            JQuery selector
	 * @param animation
	 *            animation to apply
	 * @param speed
	 *            animation speed
	 * @param callbackScript
	 *            animation callback script
	 * @return a javascript string
	 */
	public static String show(String selector, IJQAnimation animation, int speed, String callbackScript)
	{
		if (!animation.isSupportedAnimationMode(JQAnimation.ANIMATIONMODE_SHOW))
		{
			throw new JQAnimationModeNotSupportedException(JQAnimation.ANIMATIONMODE_SHOW, animation.getAnimateStyle());
		}
		return "$(" + selector + ").show('" + animation.getAnimateStyle() + "'" + (animation.getAnimateOptions().length() > 0 ? ", " + animation.getAnimateOptions() : "") + ", " + speed + ", function(){" + callbackScript + "});";
	}

	/**
	 * Generates a script to hide a Wicket component.
	 * 
	 * @param component
	 *            component to hide
	 * @return a javascript string
	 */
	public static String hide(Component component)
	{
		return hide(component, ANIMATIONSPEED_DEFAULT, "");
	}

	/**
	 * Generates a script to hide a Wicket component.
	 * 
	 * @param component
	 *            component to hide
	 * @param speed
	 *            animation speed
	 * @return a javascript string
	 */
	public static String hide(Component component, int speed)
	{
		return hide(component, speed, "");
	}

	/**
	 * Generates a script to hide a Wicket component.
	 * 
	 * @param component
	 *            component to hide
	 * @param speed
	 *            animation speed
	 * @param callbackScript
	 *            animation callback script
	 * @return a javascript string
	 */
	public static String hide(Component component, int speed, String callbackScript)
	{
		return "$('#" + component.getMarkupId() + "').hide(" + speed + ", function(){" + callbackScript + "});";
	}

	/**
	 * Generates a script to hide a Wicket component with the given animation.
	 * 
	 * @param component
	 *            component to hide
	 * @param animation
	 *            animation to apply
	 * @return a javascript string
	 */
	public static String hide(Component component, IJQAnimation animation)
	{
		return hide(component, animation, ANIMATIONSPEED_DEFAULT, "");
	}

	/**
	 * Generates a script to hide a Wicket component with the given animation.
	 * 
	 * @param component
	 *            component to hide
	 * @param animation
	 *            animation to apply
	 * @param speed
	 *            animation speed
	 * @return a javascript string
	 */
	public static String hide(Component component, IJQAnimation animation, int speed)
	{
		return hide(component, animation, speed, "");
	}

	/**
	 * Generates a script to hide a Wicket component with the given animation.
	 * 
	 * @param component
	 *            component to hide
	 * @param animation
	 *            animation to apply
	 * @param speed
	 *            animation speed
	 * @param callbackScript
	 *            animation callback script
	 * @return a javascript string
	 */
	public static String hide(Component component, IJQAnimation animation, int speed, String callbackScript)
	{
		if (!animation.isSupportedAnimationMode(JQAnimation.ANIMATIONMODE_HIDE))
		{
			throw new JQAnimationModeNotSupportedException(JQAnimation.ANIMATIONMODE_HIDE, animation.getAnimateStyle());
		}
		return "$('#" + component.getMarkupId() + "').hide('" + animation.getAnimateStyle() + "'" + (animation.getAnimateOptions().length() > 0 ? ", " + animation.getAnimateOptions() : "") + ", " + speed + ", function(){" + callbackScript + "});";
	}

	/**
	 * Generates a script to hide a JQuery selector.
	 * 
	 * @param selector
	 *            JQuery selector
	 * @return a javascript string
	 */
	public static String hide(String selector)
	{
		return hide(selector, ANIMATIONSPEED_DEFAULT, "");
	}

	/**
	 * Generates a script to hide a JQuery selector.
	 * 
	 * @param selector
	 *            JQuery selector
	 * @param speed
	 *            animation speed
	 * @return a javascript string
	 */
	public static String hide(String selector, int speed)
	{
		return hide(selector, speed, "");
	}

	/**
	 * Generates a script to hide a JQuery selector.
	 * 
	 * @param selector
	 *            JQuery selector
	 * @param speed
	 *            animation speed
	 * @param callbackScript
	 *            animation callback script
	 * @return a javascript string
	 */
	public static String hide(String selector, int speed, String callbackScript)
	{
		return "$(" + selector + ").hide(" + speed + ", function(){" + callbackScript + "});";
	}

	/**
	 * Generates a script to hide a JQuery selector with the given animation.
	 * 
	 * @param selector
	 *            JQuery selector
	 * @param animation
	 *            animation to apply
	 * @return a javascript string
	 */
	public static String hide(String selector, IJQAnimation animation)
	{
		return hide(selector, animation, ANIMATIONSPEED_DEFAULT, "");
	}

	/**
	 * Generates a script to hide a JQuery selector with the given animation.
	 * 
	 * @param selector
	 *            JQuery selector
	 * @param animation
	 *            animation to apply
	 * @param speed
	 *            animation speed
	 * @return a javascript string
	 */
	public static String hide(String selector, IJQAnimation animation, int speed)
	{
		return hide(selector, animation, speed, "");
	}

	/**
	 * Generates a script to hide a JQuery selector with the given animation.
	 * 
	 * @param selector
	 *            JQuery selector
	 * @param animation
	 *            animation to apply
	 * @param speed
	 *            animation speed
	 * @param callbackScript
	 *            animation callback script
	 * @return a javascript string
	 */
	public static String hide(String selector, IJQAnimation animation, int speed, String callbackScript)
	{
		if (!animation.isSupportedAnimationMode(JQAnimation.ANIMATIONMODE_HIDE))
		{
			throw new JQAnimationModeNotSupportedException(JQAnimation.ANIMATIONMODE_HIDE, animation.getAnimateStyle());
		}
		return "$(" + selector + ").hide('" + animation.getAnimateStyle() + "'" + (animation.getAnimateOptions().length() > 0 ? ", " + animation.getAnimateOptions() : "") + ", " + speed + ", function(){" + callbackScript + "});";
	}

	/**
	 * Generates a script to toggle a Wicket component.
	 * 
	 * @param component
	 *            component to toggle
	 * @return a javascript string
	 */
	public static String toggle(Component component)
	{
		return toggle(component, ANIMATIONSPEED_DEFAULT, "");
	}

	/**
	 * Generates a script to toggle a Wicket component.
	 * 
	 * @param component
	 *            component to toggle
	 * @param speed
	 *            animation speed
	 * @return a javascript string
	 */
	public static String toggle(Component component, int speed)
	{
		return toggle(component, speed, "");
	}

	/**
	 * Generates a script to toggle a Wicket component.
	 * 
	 * @param component
	 *            component to toggle
	 * @param speed
	 *            animation speed
	 * @param callbackScript
	 *            animation callback script
	 * @return a javascript string
	 */
	public static String toggle(Component component, int speed, String callbackScript)
	{
		return "$('#" + component.getMarkupId() + "').toggle(" + speed + ", function(){" + callbackScript + "});";
	}

	/**
	 * Generates a script to toggle a Wicket component with the given animation.
	 * 
	 * @param component
	 *            component to toggle
	 * @param animation
	 *            animation to apply
	 * @return a javascript string
	 */
	public static String toggle(Component component, IJQAnimation animation)
	{
		return toggle(component, animation, ANIMATIONSPEED_DEFAULT, "");
	}

	/**
	 * Generates a script to toggle a Wicket component with the given animation.
	 * 
	 * @param component
	 *            component to toggle
	 * @param animation
	 *            animation to apply
	 * @param speed
	 *            animation speed
	 * @return a javascript string
	 */
	public static String toggle(Component component, IJQAnimation animation, int speed)
	{
		return toggle(component, animation, speed, "");
	}

	/**
	 * Generates a script to toggle a Wicket component with the given animation.
	 * 
	 * @param component
	 *            component to toggle
	 * @param animation
	 *            animation to apply
	 * @param speed
	 *            animation speed
	 * @param callbackScript
	 *            animation callback script
	 * @return a javascript string
	 */
	public static String toggle(Component component, IJQAnimation animation, int speed, String callbackScript)
	{
		if (!animation.isSupportedAnimationMode(JQAnimation.ANIMATIONMODE_TOGGLE))
		{
			throw new JQAnimationModeNotSupportedException(JQAnimation.ANIMATIONMODE_TOGGLE, animation.getAnimateStyle());
		}
		return "$('#" + component.getMarkupId() + "').toggle('" + animation.getAnimateStyle() + "'" + (animation.getAnimateOptions().length() > 0 ? ", " + animation.getAnimateOptions() : "") + ", " + speed + ", function(){" + callbackScript + "});";
	}

	/**
	 * Generates a script to toggle a JQuery selector.
	 * 
	 * @param selector
	 *            JQuery selector
	 * @return a javascript string
	 */
	public static String toggle(String selector)
	{
		return toggle(selector, ANIMATIONSPEED_DEFAULT, "");
	}

	/**
	 * Generates a script to toggle a JQuery selector.
	 * 
	 * @param selector
	 *            JQuery selector
	 * @param speed
	 *            animation speed
	 * @return a javascript string
	 */
	public static String toggle(String selector, int speed)
	{
		return toggle(selector, speed, "");
	}

	/**
	 * Generates a script to toggle a JQuery selector.
	 * 
	 * @param selector
	 *            JQuery selector
	 * @param speed
	 *            animation speed
	 * @param callbackScript
	 *            animation callback script
	 * @return a javascript string
	 */
	public static String toggle(String selector, int speed, String callbackScript)
	{
		return "$(" + selector + ").toggle(" + speed + ", function(){" + callbackScript + "});";
	}

	/**
	 * Generates a script to toggle a JQuery selector.
	 * 
	 * @param selector
	 *            JQuery selector
	 * @param animation
	 *            animation to apply
	 * @return a javascript string
	 */
	public static String toggle(String selector, IJQAnimation animation)
	{
		return toggle(selector, animation, ANIMATIONSPEED_DEFAULT, "");
	}

	/**
	 * Generates a script to toggle a JQuery selector.
	 * 
	 * @param selector
	 *            JQuery selector
	 * @param animation
	 *            animation to apply
	 * @param speed
	 *            animation speed
	 * @return a javascript string
	 */
	public static String toggle(String selector, IJQAnimation animation, int speed)
	{
		return toggle(selector, animation, speed, "");
	}

	/**
	 * Generates a script to toggle a JQuery selector.
	 * 
	 * @param selector
	 *            JQuery selector
	 * @param animation
	 *            animation to apply
	 * @param speed
	 *            animation speed
	 * @param callbackScript
	 *            animation callbackScript
	 * @return a javascript string
	 */
	public static String toggle(String selector, IJQAnimation animation, int speed, String callbackScript)
	{
		if (!animation.isSupportedAnimationMode(JQAnimation.ANIMATIONMODE_TOGGLE))
		{
			throw new JQAnimationModeNotSupportedException(JQAnimation.ANIMATIONMODE_TOGGLE, animation.getAnimateStyle());
		}
		return "$(" + selector + ").toogle('" + animation.getAnimateStyle() + "'" + (animation.getAnimateOptions().length() > 0 ? ", " + animation.getAnimateOptions() : "") + ", " + speed + ", function(){" + callbackScript + "});";
	}

	// TODO
	// public static String addClass(String classNames, int speed)
	// {
	// return addClass(classNames, ANIMATIONSPEED_DEFAULT, "", "");
	// }

	// TODO
	// public static String addClass(String classNames, int speed, String easing)
	// {
	// return addClass(classNames, speed, "", "");
	// }

	// TODO
	// public static String addClass(String classNames, int speed, String easing, String callbackScript)
	// {
	// return "";
	// }

	// TODO
	// public static String removeClass(String classNames, int speed)
	// {
	// return removeClass(classNames, ANIMATIONSPEED_DEFAULT, "", "");
	// }

	// TODO
	// public static String removeClass(String classNames, int speed, String easing)
	// {
	// return removeClass(classNames, speed, "", "");
	// }

	// TODO
	// public static String removeClass(String classNames, int speed, String easing, String callbackScript)
	// {
	// return "";
	// }

	// TODO
	// public static String toggleClass(String classNames, int speed)
	// {
	// return removeClass(classNames, ANIMATIONSPEED_DEFAULT, "", "");
	// }

	// TODO
	// public static String toggleClass(String classNames, int speed, String easing)
	// {
	// return removeClass(classNames, speed, "", "");
	// }

	// TODO
	// public static String toggleClass(String classNames, int speed, String easing, String callbackScript)
	// {
	// return "";
	// }

	// TODO
	// public static String morph(String remove, String add, int speed, String easing)
	// {
	// return morph(remove, add, speed, easing, "");
	// }

	// TODO
	// public static String morph(String remove, String add, int speed, String easing, String callbackScript)
	// {
	// return "";
	// }

}
